/*
 * TemplateReader.java
 *
 * Copyright (c) 2008 Teamnet. All Rights Reserved.
 *
 * This source file may not be copied, modified or redistributed,
 * in whole or in part, in any form or for any reason, without the express
 * written consent of Teamnet.
 */

package ro.prjmanager.template;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.io.VelocityWriter;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.app.VelocityEngine;
import org.apache.geronimo.mail.util.StringBufferOutputStream;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import ro.prj.manager.svn.PrjSvnManager;
import ro.prjmanager.template.form.ClassFileForm;
import ro.prjmanager.velocity.GeneratorContext;

import java.io.*;

/**
 * This class is used to generate file from a template file
 */
public class TemplateReader {
    private static Log log = LogFactory.getLog(TemplateReader.class);

    /**
     * This method extracts the inputStream object from relative file path specified
     * @param relativePath - Relative file path to project root path
     * @return - InputStream object coresponding to relative path specified as param
     */
    private static InputStream readTemplate(String relativePath){
        Resource prop=new ClassPathResource(relativePath);
        InputStream is=null;
        try {
            is=prop.getInputStream();
        } catch (IOException e) {
            e.printStackTrace();
            log.error(e);
        }
        return is;
    }

    /**
     * This method is called to generate an java file given the form template
     * @param classTemplate - ClassFileForm object
     */
    public static void generateClassFile(ClassFileForm classTemplate){
        String fileOutputPath = classTemplate.getGeneratedFilePath();
        try {
            InputStream is = readTemplate(classTemplate.getTemplatePath());
            GeneratorContext context = new GeneratorContext(classTemplate);
            File f=new File("C:/test.txt");
            FileWriter w=new FileWriter(f);





            mergeTemplate1(w,context, "Class" + fileOutputPath, is);
            FileInputStream fr=new FileInputStream(f);
            byte b[]=new byte[fr.available()];

            fr.read(b);

            File f1=new File(fileOutputPath);
            PrjSvnManager prjSvnManager= PrjSvnManager.instanceFromProperties();

            String dirPath=fileOutputPath.substring(0,fileOutputPath.lastIndexOf("/"));
            String fileName=fileOutputPath.substring(fileOutputPath.lastIndexOf("/"),fileOutputPath.length());
            System.out.println(f1.getParent());
            System.out.println(f1.getName());
            prjSvnManager.doSvnFile(dirPath,fileName,b);




        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    private static void mergeTemplate1(FileWriter w,VelocityContext context, String name, InputStream is) {
        try {
            Velocity.init();
            String ff = getInputStreamAsString(is);

            Velocity.evaluate(context, w, name, ff);
            w.close();
        } catch (Exception e) {
            log.error(e);
        }
    }


    public static byte[] evaluate(VelocityContext context,String name,byte[] b){
        byte[] ret=null;
        ByteArrayOutputStream outStr=new ByteArrayOutputStream();
        InputStream is=new ByteArrayInputStream(b);
        OutputStreamWriter w=new OutputStreamWriter(outStr);
        try {
            Velocity.init();
            Velocity.evaluate(context,w,name, getInputStreamAsString(is));
            w.flush();
            ret=outStr.toByteArray();
            w.close();
        } catch (IOException e) {
            log.error(e);
            e.printStackTrace();
        } catch (Exception e) {
            log.error(e);
            e.printStackTrace();
        }

        return ret;
    }


    private static String getInputStreamAsString(InputStream inputStream) throws IOException {
        StringBuffer sb = new StringBuffer();
        int ch;
        while ((ch = inputStream.read()) != -1) {
            sb.append((char) ch);
        }
        return sb.toString();
    }


}
